package com.kbbywyclient.util;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.widget.ImageView;

import com.kbbywyclient.app.App;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Transformation;

/**
 * Created by Jiangzx on 2017/5/11.
 * 图片加载类
 */

public class ImageLoaderUtils {
    private ImageLoaderUtils(){
        //私有化构造方法
    }

    /**加载普通图片*/
    public static void displayImage(ImageView imageView,String imageUrl){
        Picasso.with(App.getInstance()).
                load(imageUrl).
                config(Bitmap.Config.RGB_565).
                into(imageView);
    }

    /**加载图片，圆角显示*/
    public static void displayImage(ImageView imageView,String imageUrl,int radius){
        Picasso.with(App.getInstance()).
                load(imageUrl).
                config(Bitmap.Config.RGB_565).
                transform(new RoundedCornersTransformation(radius,0)).
                into(imageView);
    }

    /**加载图片，加载时与加载失败时显示默认图片*/
    public static void displayImageDefaultRes(ImageView imageView,String imageUrl,int bitmapRes){
        Picasso.with(App.getInstance()).
                load(imageUrl).
                config(Bitmap.Config.RGB_565).
                placeholder(bitmapRes).
                error(bitmapRes).
                into(imageView);
    }

    /**加载图片，圆角显示，加载时与加载失败时显示默认图片*/
    public static void displayImageCornerDefaultRes(ImageView imageView,String imageUrl,
                                             int radius,int bitmapRes){
        Picasso.with(App.getInstance()).
                load(imageUrl).
                config(Bitmap.Config.RGB_565).
                placeholder(bitmapRes).
                error(bitmapRes).
                transform(new RoundedCornersTransformation(radius,0)).
                into(imageView);
    }

    public static class RoundedCornersTransformation implements Transformation {
        public enum CornerType {
            ALL,
            TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,
            TOP, BOTTOM, LEFT, RIGHT,
            OTHER_TOP_LEFT, OTHER_TOP_RIGHT, OTHER_BOTTOM_LEFT, OTHER_BOTTOM_RIGHT,
            DIAGONAL_FROM_TOP_LEFT, DIAGONAL_FROM_TOP_RIGHT
        }

        private int mRadius;
        private int mDiameter;
        private int mMargin;
        private CornerType mCornerType;

        public RoundedCornersTransformation(int radius, int margin) {
            this(radius, margin, CornerType.ALL);
        }

        public RoundedCornersTransformation(int radius, int margin, CornerType cornerType) {
            mRadius = radius;
            mDiameter = radius * 2;
            mMargin = margin;
            mCornerType = cornerType;
        }

        @Override public Bitmap transform(Bitmap source) {

            int width = source.getWidth();
            int height = source.getHeight();

            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
            drawRoundRect(canvas, paint, width, height);
            source.recycle();

            return bitmap;
        }

        private void drawRoundRect(Canvas canvas, Paint paint, float width, float height) {
            float right = width - mMargin;
            float bottom = height - mMargin;

            switch (mCornerType) {
                case ALL:
                    canvas.drawRoundRect(new RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, paint);
                    break;
                case TOP_LEFT:
                    drawTopLeftRoundRect(canvas, paint, right, bottom);
                    break;
                case TOP_RIGHT:
                    drawTopRightRoundRect(canvas, paint, right, bottom);
                    break;
                case BOTTOM_LEFT:
                    drawBottomLeftRoundRect(canvas, paint, right, bottom);
                    break;
                case BOTTOM_RIGHT:
                    drawBottomRightRoundRect(canvas, paint, right, bottom);
                    break;
                case TOP:
                    drawTopRoundRect(canvas, paint, right, bottom);
                    break;
                case BOTTOM:
                    drawBottomRoundRect(canvas, paint, right, bottom);
                    break;
                case LEFT:
                    drawLeftRoundRect(canvas, paint, right, bottom);
                    break;
                case RIGHT:
                    drawRightRoundRect(canvas, paint, right, bottom);
                    break;
                case OTHER_TOP_LEFT:
                    drawOtherTopLeftRoundRect(canvas, paint, right, bottom);
                    break;
                case OTHER_TOP_RIGHT:
                    drawOtherTopRightRoundRect(canvas, paint, right, bottom);
                    break;
                case OTHER_BOTTOM_LEFT:
                    drawOtherBottomLeftRoundRect(canvas, paint, right, bottom);
                    break;
                case OTHER_BOTTOM_RIGHT:
                    drawOtherBottomRightRoundRect(canvas, paint, right, bottom);
                    break;
                case DIAGONAL_FROM_TOP_LEFT:
                    drawDiagonalFromTopLeftRoundRect(canvas, paint, right, bottom);
                    break;
                case DIAGONAL_FROM_TOP_RIGHT:
                    drawDiagonalFromTopRightRoundRect(canvas, paint, right, bottom);
                    break;
                default:
                    canvas.drawRoundRect(new RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, paint);
                    break;
            }
        }

        private void drawTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, mMargin + mDiameter),
                    mRadius, mRadius, paint);
            canvas.drawRect(new RectF(mMargin, mMargin + mRadius, mMargin + mRadius, bottom), paint);
            canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom), paint);
        }

        private void drawTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, mMargin + mDiameter), mRadius,
                    mRadius, paint);
            canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom), paint);
            canvas.drawRect(new RectF(right - mRadius, mMargin + mRadius, right, bottom), paint);
        }

        private void drawBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, mMargin + mDiameter, bottom),
                    mRadius, mRadius, paint);
            canvas.drawRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom - mRadius), paint);
            canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom), paint);
        }

        private void drawBottomRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(right - mDiameter, bottom - mDiameter, right, bottom), mRadius,
                    mRadius, paint);
            canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom), paint);
            canvas.drawRect(new RectF(right - mRadius, mMargin, right, bottom - mRadius), paint);
        }

        private void drawTopRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin, mMargin + mRadius, right, bottom), paint);
        }

        private void drawBottomRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin, mMargin, right, bottom - mRadius), paint);
        }

        private void drawLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom), paint);
        }

        private void drawRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom), paint);
        }

        private void drawOtherTopLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom - mRadius), paint);
        }

        private void drawOtherTopRightRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin + mRadius, mMargin, right, bottom - mRadius), paint);
        }

        private void drawOtherBottomLeftRoundRect(Canvas canvas, Paint paint, float right, float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
                    paint);
            canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin, mMargin + mRadius, right - mRadius, bottom), paint);
        }

        private void drawOtherBottomRightRoundRect(Canvas canvas, Paint paint, float right,
                                                   float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
                    paint);
            canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
                    paint);
            canvas.drawRect(new RectF(mMargin + mRadius, mMargin + mRadius, right, bottom), paint);
        }

        private void drawDiagonalFromTopLeftRoundRect(Canvas canvas, Paint paint, float right,
                                                      float bottom) {
            canvas.drawRoundRect(new RectF(mMargin, mMargin, mMargin + mDiameter, mMargin + mDiameter),
                    mRadius, mRadius, paint);
            canvas.drawRoundRect(new RectF(right - mDiameter, bottom - mDiameter, right, bottom), mRadius,
                    mRadius, paint);
            canvas.drawRect(new RectF(mMargin, mMargin + mRadius, right - mDiameter, bottom), paint);
            canvas.drawRect(new RectF(mMargin + mDiameter, mMargin, right, bottom - mRadius), paint);
        }

        private void drawDiagonalFromTopRightRoundRect(Canvas canvas, Paint paint, float right,
                                                       float bottom) {
            canvas.drawRoundRect(new RectF(right - mDiameter, mMargin, right, mMargin + mDiameter), mRadius,
                    mRadius, paint);
            canvas.drawRoundRect(new RectF(mMargin, bottom - mDiameter, mMargin + mDiameter, bottom),
                    mRadius, mRadius, paint);
            canvas.drawRect(new RectF(mMargin, mMargin, right - mRadius, bottom - mRadius), paint);
            canvas.drawRect(new RectF(mMargin + mRadius, mMargin + mRadius, right, bottom), paint);
        }

        @Override public String key() {
            return "RoundedTransformation(radius=" + mRadius + ", margin=" + mMargin + ", diameter="
                    + mDiameter + ", cornerType=" + mCornerType.name() + ")";
        }
    }
}
